#include <log4cxx/logger.h>
#include <json/json.h>

#include "DataSvrClientProtoHelper.h"
#include "ProtoHelper.h"
#include "DataSvrCommon.h"

using namespace log4cxx;

static LoggerPtr g_logger = Logger::getLogger("DataSvrClientProtoHelper");

string ds_build_request_create_file(int32_t dir_id, int64_t file_id) {
	if (dir_id < 0 || file_id < 0) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid args");
                return "";
        }
        json_object * j = json_object_new_object();
        json_object * j_cmd_id = json_object_new_int(DS_CMD_CREATE_FILE);
        json_object * j_dir_id = json_object_new_int(dir_id);
        json_object * j_file_id = json_object_new_int(file_id);
        json_object_object_add(j, "CMD_ID", j_cmd_id);
        json_object_object_add(j, "DIR_ID", j_dir_id);
        json_object_object_add(j, "FILE_ID", j_file_id);
        string request = json_object_to_json_string(j);
        json_object_put(j);
        return request;
}

string ds_build_request_delete_file(int32_t dir_id, int64_t file_id) {
	if (dir_id < 0 || file_id < 0) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid args");
                return "";
        }
        json_object * j = json_object_new_object();
        json_object * j_cmd_id = json_object_new_int(DS_CMD_DELETE_FILE);
        json_object * j_dir_id = json_object_new_int(dir_id);
        json_object * j_file_id = json_object_new_int(file_id);
        json_object_object_add(j, "CMD_ID", j_cmd_id);
        json_object_object_add(j, "DIR_ID", j_dir_id);
        json_object_object_add(j, "FILE_ID", j_file_id);
        string request = json_object_to_json_string(j);
        json_object_put(j);
        return request;
}

string ds_build_request_read_file(int32_t dir_id, int64_t file_id, int64_t begin_pos, int32_t len) {
	if (dir_id < 0 || file_id < 0 || begin_pos < 0 || len < 0) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid args");
                return "";
        }
        json_object * j = json_object_new_object();
       	json_object * j_cmd_id = json_object_new_int(DS_CMD_READ_FILE);
        json_object * j_dir_id = json_object_new_int(dir_id);
        json_object * j_file_id = json_object_new_int(file_id);
        json_object * j_begin_pos = json_object_new_int(begin_pos);
        json_object * j_len = json_object_new_int(len);
        json_object_object_add(j, "CMD_ID", j_cmd_id);
        json_object_object_add(j, "DIR_ID", j_dir_id);
        json_object_object_add(j, "FILE_ID", j_file_id);
        json_object_object_add(j, "BEGIN_POS", j_begin_pos);
        json_object_object_add(j, "LEN", j_len);
        string request = json_object_to_json_string(j);
        json_object_put(j);
        return request;
}

string ds_build_request_write_file(int32_t dir_id, int64_t file_id, int64_t begin_pos, int32_t len, int32_t mode) {
	if (dir_id < 0 || file_id < 0 || begin_pos < 0 || len < 0 ) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid args");
                return "";
        }
        json_object * j = json_object_new_object();
       	json_object * j_cmd_id = json_object_new_int(DS_CMD_WRITE_FILE);
        json_object * j_dir_id = json_object_new_int(dir_id);
        json_object * j_file_id = json_object_new_int(file_id);
        json_object * j_begin_pos = json_object_new_int(begin_pos);
        json_object * j_len = json_object_new_int(len);
        json_object * j_mode = json_object_new_int(mode);
        json_object_object_add(j, "CMD_ID", j_cmd_id);
        json_object_object_add(j, "DIR_ID", j_dir_id);
        json_object_object_add(j, "FILE_ID", j_file_id);
        json_object_object_add(j, "BEGIN_POS", j_begin_pos);
        json_object_object_add(j, "LEN", j_len);
        json_object_object_add(j, "MODE", j_mode);
        string request = json_object_to_json_string(j);
        json_object_put(j);
        return request;
}

string ds_build_request_get_file_control_info(int32_t dir_id, int64_t file_id) {
	if (dir_id < 0 || file_id < 0) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid args");
                return "";
        }
        json_object * j = json_object_new_object();
        json_object * j_cmd_id = json_object_new_int(DS_CMD_GET_FILE_CONTROL_INFO);
        json_object * j_dir_id = json_object_new_int(dir_id);
        json_object * j_file_id = json_object_new_int(file_id);
        json_object_object_add(j, "CMD_ID", j_cmd_id);
        json_object_object_add(j, "DIR_ID", j_dir_id);
        json_object_object_add(j, "FILE_ID", j_file_id);
        string request = json_object_to_json_string(j);
        json_object_put(j);
        return request;
}


string ds_build_request_replicate(int32_t dir_id, int64_t file_id, int32_t src_ds_id, int64_t src_file_size, \
					vector<uint32_t> src_crcs) { 
	if (dir_id < 0 || file_id < 0 || src_ds_id < 0 || src_file_size < 0) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid args");
                return "";
        }
        json_object * j = json_object_new_object();
        json_object * j_cmd_id = json_object_new_int(DS_CMD_REPLICATE);
        json_object * j_dir_id = json_object_new_int(dir_id);
        json_object * j_file_id = json_object_new_int(file_id);
        json_object * j_src_ds_id = json_object_new_int(src_ds_id);
        json_object * j_src_file_size = json_object_new_int(src_file_size);
	 json_object * j_src_crcs = json_object_new_array();
         for(vector<uint32_t>::const_iterator iter = src_crcs.begin(); src_crcs.end() != iter; iter++) {
                json_object * j_crc = json_object_new_int(*iter);
                json_object_array_add(j_src_crcs, j_crc);
        }
        json_object_object_add(j, "CMD_ID", j_cmd_id);
        json_object_object_add(j, "DIR_ID", j_dir_id);
        json_object_object_add(j, "FILE_ID", j_file_id);
        json_object_object_add(j, "SRC_DS_ID", j_src_ds_id);
        json_object_object_add(j, "SRC_FILE_SIZE", j_src_file_size);
        json_object_object_add(j, "SRC_CRC", j_src_crcs);
        string request = json_object_to_json_string(j);
        json_object_put(j);
        return request;
}

string ds_build_request_truncate(int32_t dir_id, int64_t file_id, int64_t size) {
	if (dir_id < 0 || file_id < 0 || size < 0) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid args");
                return "";
        }
        json_object * j = json_object_new_object();
        json_object * j_cmd_id = json_object_new_int(DS_CMD_TRUNCATE);
        json_object * j_dir_id = json_object_new_int(dir_id);
        json_object * j_file_id = json_object_new_int(file_id);
        json_object * j_size = json_object_new_int(size);
        json_object_object_add(j, "CMD_ID", j_cmd_id);
        json_object_object_add(j, "DIR_ID", j_dir_id);
        json_object_object_add(j, "FILE_ID", j_file_id);
        json_object_object_add(j, "SIZE", j_size);
        string request = json_object_to_json_string(j);
        json_object_put(j);
        return request;
}




int ds_parse_response_create_file(const char * response, int32_t & result) {
        if (NULL == response) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid args");
                return -1;
        }
        json_object * j = json_tokener_parse(response);
        if (is_error(j)) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", parse response err:" << response);
                return -2;
        }
        json_object * j_result = json_object_object_get(j, "RESULT");
        if (is_error(j_result)) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", no RESULT found in response:" << response);
                json_object_put(j);
                return -3;
        }
        result = json_object_get_int(j_result);
        json_object_put(j);
        return 1;
}

int ds_parse_response_delete_file(const char * response, int32_t & result) {
        if (NULL == response) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid args");
                return -1;
        }
        json_object * j = json_tokener_parse(response);
        if (is_error(j)) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", parse response err:" << response);
                return -2;
        }
        json_object * j_result = json_object_object_get(j, "RESULT");
        if (is_error(j_result)) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", no RESULT found in response:" << response);
                json_object_put(j);
                return -3;
        }
        result = json_object_get_int(j_result);
        json_object_put(j);
        return 1;
}


int ds_parse_response_read_file(const char * response, int32_t & result) {
        if (NULL == response) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid args");
                return -1;
        }
        json_object * j = json_tokener_parse(response);
        if (is_error(j)) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", parse response err:" << response);
                return -2;
        }
        json_object * j_result = json_object_object_get(j, "RESULT");
        if (is_error(j_result)) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", no RESULT found in response:" << response);
                json_object_put(j);
                return -3;
        }
        result = json_object_get_int(j_result);
        json_object_put(j);
        return 1;
}


int ds_parse_response_write_file(const char * response, int32_t & result) {
        if (NULL == response) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid args");
                return -1;
        }
        json_object * j = json_tokener_parse(response);
        if (is_error(j)) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", parse response err:" << response);
                return -2;
        }
        json_object * j_result = json_object_object_get(j, "RESULT");
        if (is_error(j_result)) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", no RESULT found in response:" << response);
                json_object_put(j);
                return -3;
        }
        result = json_object_get_int(j_result);
        json_object_put(j);
        return 1;
}


int ds_parse_response_replicate(const char * response, int32_t & result) {
        if (NULL == response) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid args");
                return -1;
        }
        json_object * j = json_tokener_parse(response);
        if (is_error(j)) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", parse response err:" << response);
                return -2;
        }
        json_object * j_result = json_object_object_get(j, "RESULT");
        if (is_error(j_result)) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", no RESULT found in response:" << response);
                json_object_put(j);
                return -3;
        }
        result = json_object_get_int(j_result);
        json_object_put(j);
        return 1;
}

int ds_parse_response_get_file_control_info(const char * response, int32_t & result, DS_FILE_CONTROL_INFO & info, \
						int64_t & file_size) {
        if (NULL == response) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid args");
                return -1;
        }
        json_object * j = json_tokener_parse(response);
        if (is_error(j)) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", parse response err:" << response);
                return -2;
        }
        json_object * j_result = json_object_object_get(j, "RESULT");
        json_object * j_crc = json_object_object_get(j, "CRC");
        json_object * j_file_size = json_object_object_get(j, "FILE_SIZE");
        if (NULL == j_result || NULL == j_crc || NULL == j_file_size) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", response content error:" << response);
                json_object_put(j);
                return -3;
        }
        file_size = json_object_get_int(j_file_size);
        result = json_object_get_int(j_result);
	if (OK_RESULT == result) {
		for(int i=0; i < json_object_array_length(j_crc); i++) {
			json_object * j_t = json_object_array_get_idx(j_crc, i);
			info.crcs.push_back(json_object_get_int(j_t));
		}
	}
	json_object_put(j);
        return 1;
}

int ds_parse_response_truncate(const char * response, int32_t & result) {
        if (NULL == response) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid args");
                return -1;
        }
        json_object * j = json_tokener_parse(response);
        if (is_error(j)) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", parse response err:" << response);
                return -2;
        }
        json_object * j_result = json_object_object_get(j, "RESULT");
        if (NULL == j_result) {
                LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", no RESULT found in response:" << response);
                json_object_put(j);
                return -3;
        }
        result = json_object_get_int(j_result);
        json_object_put(j);
        return 1;
}
